import logging
import time
import os
import math

import numpy as np

import pydirectinput as pdg
import pyautogui as pag
pdg.FAILSAFE = False

resolution = (1280, 960)
CENTER_X = int(resolution[0] / 2)
CENTER_Y = int(resolution[1] / 2)


def count_down(count=5):
    for i in reversed(list(range(count))):
        print(f"时间：{i}")
        time.sleep(1)


def double_click():
    pdg.mouseDown()
    pdg.mouseUp()
    pdg.mouseDown()
    pdg.mouseUp()


def click(button="left"):
    pdg.mouseDown(button=button)
    pdg.mouseUp(button=button)


def move_forward(interval=0, pause_count=0, step_limit=5, margin=0):
    step_count = 0
    while True:
        pdg.moveTo(CENTER_X, CENTER_Y + margin, duration=1)
        click(button="left")
        time.sleep(interval)
        step_count += 1
        logging.info(f"移动步数：{step_count}")
        if step_limit is not None and step_count >= step_limit:
            break

        if step_count % pause_count == 0:
            count_down(5)


def rotate(round=1, direction="left"):
    for i in range(round):
        pdg.press(direction)


def get_item_pos(image_path):
    target_pos = pag.locateOnScreen(image_path)
    goto_pos = pag.center(target_pos)
    return goto_pos


def locate_click(image_path, sleep_second=0):
    x, y = get_item_pos(image_path)
    pdg.moveTo(x, y, duration=1)
    time.sleep(sleep_second)
    pdg.mouseDown()
    pdg.mouseUp()
    return (x, y)


def point_screen(sx=300, sy=300):
    pag.moveTo(sx, sy)
    # click()
    pdg.click()


def screenshot_coor(coor, image_path, point_and_save=False, expand=0):
    X1, Y1, X2, Y2 = coor
    if point_and_save:
        # 指的是要截取的弹出来的对话框，就要然光标指向该区域中心
        X_center = int((X1 + X2) / 2)
        Y_center = int((Y1 + Y2) / 2)
        pdg.moveTo(X_center, Y_center)
    X1 -= expand
    Y2 -= expand
    width = X2 - X1 + expand
    height = Y2 - Y1 + expand
    screenshot = pag.screenshot(region=(X1, Y1, width, height))
    screenshot.save(image_path)
    return image_path


def cal_angle(line1, line2):
    try:
        # 计算两条直线的斜率
        vector_AB = [line1[1][0] - line1[0][0], line1[1][1] - line1[0][1]]
        vector_CD = [line2[1][0] - line2[0][0], line2[1][1] - line2[0][1]]

        # 计算向量AB和向量CD的点积
        dot_product = vector_AB[0] * vector_CD[0] + vector_AB[1] * vector_CD[1]

        # 计算向量AB和向量CD的模
        magnitude_AB = math.sqrt(vector_AB[0] ** 2 + vector_AB[1] ** 2)
        magnitude_CD = math.sqrt(vector_CD[0] ** 2 + vector_CD[1] ** 2)

        # 计算夹角的弧度
        angle_rad = math.acos(dot_product / (magnitude_AB * magnitude_CD))

        # 将弧度转换为角度
        angle_degrees = math.degrees(angle_rad)
    except Exception as e:
        logging.info(f"错误：{e}")
        angle_degrees = None
    return angle_degrees


def get_vector_angle(vector1, vector2):
    line1 = [(0, 0), vector1]
    line2 = [(0, 0), vector2]
    return cal_angle(line1, line2)

def get_vector(start, end):
    return (end[0] - start[0], end[1] - start[1])


def get_vector_quadrant(vector):
    if vector[0] > 0 and vector[1] > 0:
        return 1
    elif vector[0] < 0 and vector[1] > 0:
        return 2
    elif vector[0] < 0 and vector[1] < 0:
        return 3
    else:
        return 4


def get_relation_with_line(point, line):
    if line[0] != 0:
        k = line[1] / line[0]
        yp_in_line = k * point[0]
        if point[1] < yp_in_line:
            return "below"
        elif point[1] > yp_in_line:
            return "above"
        else:
            return "on"
    return None


def get_rotation_direction(start, end, target):
    # "clockwise":right
    # "anticlockwise":"left
    vector_ab = get_vector(start, target)
    vector_ac = get_vector(start, end)
    quadrant_ab = get_vector_quadrant(vector_ab)
    # quadrant_ac = get_vector_quadrant(vector_ac)
    logging.info(f"AB向量所在的象限：{quadrant_ab}")

    relation = get_relation_with_line(vector_ac, vector_ab)
    logging.info(f"relation:{relation}")

    if relation is not None:
        if quadrant_ab in (1, 4):
            if relation == "above":
                direction = "right"
            else:
                direction = "left"
        else:
            if relation == "above":
                direction = "left"
            else:
                direction = "right"
    else:
        direction = None
    return direction


def cal_move_point(point, target_point, unit_d=6):
    Xp, Yp = point
    Xt, Yt = target_point
    # print("(Xp - Xt)^2:", (Xp - Xt)**2)
    distance = math.sqrt((Xp - Xt) ** 2 + (Yp - Yt) ** 2)
    print("distance:", distance)
    ratio = unit_d / distance
    Xe = Xp + ratio * (Xt - Xp)
    Ye = Yp + ratio * (Yt - Yp)
    return (Xe, Ye)


def get_euclidean_distance(point1, point2):
    distance = math.sqrt((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2)
    return distance


def check_in_range(point, target_point, criterion=3):
    distance = get_euclidean_distance(point, target_point)
    print("distance:", distance)
    if distance <= criterion:
        return True
    else:
        return False


def angle_between_vectors(vector1, vector2):
    dot_product = np.dot(vector1, vector2)
    norm_product = np.linalg.norm(vector1) * np.linalg.norm(vector2)
    angle = np.arccos(dot_product / norm_product)
    if not np.isnan(angle):
        return int(np.degrees(angle))
    return None


def get_rotation_angle(line1, line2):
    vector1 = [line1[1][0] - line1[0][0], line1[1][1] - line1[0][1]]
    vector2 = [line2[1][0] - line2[0][0], line2[1][1] - line2[0][1]]
    angle = angle_between_vectors(vector1, vector2)
    return angle
    # angle = cal_angle(line1, line2)
    # if angle is not None:
    #     rotation_angle = 180 - angle
    # else:
    #     rotation_angle = 0
    # logging.info(f"转动角度:{rotation_angle}")
    # return rotation_angle

# def get_angle_and_direction(line1, line2):
#     angle = get_rotation_angle(line1, line2)
#     direction =


def get_rotation_round(line1, line2, rotation_unit=8):
    angle = get_rotation_angle(line1, line2)
    if angle is not None:
        return round(angle / rotation_unit)
    return None